package com.jysz.certificate.service.system;

import java.util.Iterator;
import java.util.List;

import javax.annotation.Resource;

import org.apache.commons.lang.StringUtils;
import org.hibernate.Criteria;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Projections;
import org.hibernate.criterion.Restrictions;
import org.hibernate.criterion.Subqueries;
import org.springframework.stereotype.Service;

import com.jysz.certificate.Constants;
import com.jysz.certificate.persistence.dao.system.MenuDao;
import com.jysz.certificate.persistence.enums.PostType;
import com.jysz.certificate.persistence.model.system.Menu;
import com.jysz.certificate.persistence.model.system.Oper;
import com.jysz.certificate.persistence.model.system.User;
import com.jysz.webcore.ssh.orm.hibernate.support.Page;
import com.jysz.webcore.ssh.service.EntityService;

@Service
public class MenuService extends EntityService<Menu, Long, MenuDao>{
	
	@Resource
	private MenuDao menuDao;

	@Override
	public MenuDao getEntityDao() {
		return menuDao;
	}

	public Page<Menu> findPage(Menu search, int pageNo, int pageSize) {
		Criteria criteria = menuDao.createCriteria();
		criteria.addOrder(Order.asc(Menu.COLUMN_CODE));
		criteria.addOrder(Order.desc(Menu.COLUMN_ORDER));
		
		if(search != null && StringUtils.isNotBlank(search.getName())){
			criteria.add(Restrictions.like(Menu.COLUMN_NAME, search.getName(), MatchMode.ANYWHERE));
		}
		return this.findPage(criteria, 0, 10000);
	}

	public Integer getMaxOrder(Long parentId) {
		Menu menu = null;
		if(parentId != null ){
			menu = menuDao.get(parentId);
		}
		return menuDao.getMaxOrder(menu);
	}

	public String genCode(Long parentId) {
		Menu menu = null;
		if(parentId != null ){
			menu = menuDao.get(parentId);
		}
		Integer order = this.getMaxOrder(parentId) + 1;
		String code = menu != null ? menu.getCode() + "_" + String.format("%1$03d", order) : Constants.CODE_PREFIX_MENU + String.format("%1$03d", order);
		
		return code;
	}

	public void saveUpdateChildCode(Menu menu) {
		List<Menu> menus = menu.getChildMenu();
		
		if(menus == null || menus.size() < 1){
			return;
		}
		
		for (Iterator<Menu> iterator = menus.iterator(); iterator.hasNext();) {
			Menu entity = iterator.next();
			
			entity.setCode(menu.getCode() +"_" + String.format("%1$03d", entity.getOrder()));
			
			this.save(entity);
		}
	}

	public List<Menu> findTopMenus() {
		
		return menuDao.findTopMenus();
	}
	
	//查找有权限的根菜单
	public List<Menu> findTopMenusByPermission(User user){
		if(user == null)
			return null;
		if(user.getPost().compareTo(PostType.Admin)==0)
			return findTopMenus();
		DetachedCriteria dc = DetachedCriteria.forClass(Oper.class);
		DetachedCriteria roleOperRefListCriteria = dc.createCriteria("roleOperRefList");
		DetachedCriteria roleCriteria = roleOperRefListCriteria.createCriteria("role");
		DetachedCriteria usersCriteria = roleCriteria.createCriteria("users");
		usersCriteria.add(Restrictions.eq("id", user.getId()));
		
		dc.setProjection(Projections.projectionList().add(Projections.groupProperty("code")));
		Criteria criteria = menuDao.createCriteria();

		criteria.add(Restrictions.eq(Menu.COLUMN_GRADE, 1));
		
		criteria.add(Subqueries.propertyIn("code", dc));
		criteria.addOrder(Order.asc(Menu.COLUMN_ORDER));
		
		return criteria.list();
	}
	
	//查找有权限的子菜单菜单
		public List<Menu> findChildMenusByPermission(User user,Menu parent){
			if(user==null)
				return null;
			if(user.getPost().compareTo(PostType.Admin)==0)
				return parent.getChildMenu();
			DetachedCriteria dc = DetachedCriteria.forClass(Oper.class);
			DetachedCriteria roleOperRefListCriteria = dc.createCriteria("roleOperRefList");
			DetachedCriteria roleCriteria = roleOperRefListCriteria.createCriteria("role");
			DetachedCriteria usersCriteria = roleCriteria.createCriteria("users");
			usersCriteria.add(Restrictions.eq("id", user.getId()));
			
			dc.setProjection(Projections.projectionList().add(Projections.groupProperty("code")));
			Criteria criteria = menuDao.createCriteria();

			criteria.add(Restrictions.eq(Menu.COLUMN_PARENT, parent));
			
			criteria.add(Subqueries.propertyIn("code", dc));
			criteria.addOrder(Order.asc(Menu.COLUMN_ORDER));
			
			return criteria.list();
		}
}
